@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)

import kotlinx.cinterop.*
import platform.posix.*

fun main() {
    // 初始化互补碱基映射表（包含大小写）
    val complement = ByteArray(256)
    for (i in 0 until 256) {
        complement[i] = i.toByte()
    }
    complement['A'.code] = 'T'.code.toByte()
    complement['T'.code] = 'A'.code.toByte()
    complement['C'.code] = 'G'.code.toByte()
    complement['G'.code] = 'C'.code.toByte()
    complement['a'.code] = 't'.code.toByte()
    complement['t'.code] = 'a'.code.toByte()
    complement['c'.code] = 'g'.code.toByte()
    complement['g'.code] = 'c'.code.toByte()

    try {
        // 读取 dna.txt 文件内容
        val input = readFile("/Users/huawei/IdeaProjects/dy_kmp_testcases/src/main/kotlin/src/main/kotlin/dna.txt")

        // 过滤非碱基字符（修复类型推断问题）
        val filtered = input.filterIsInstance<Byte>()
            .filter { byte ->
                val c = byte.toInt().toChar()
                c in setOf('A', 'T', 'C', 'G', 'a', 't', 'c', 'g')
            }.toByteArray()

        // 计算反向互补序列
        val result = reverseComplement(filtered, complement)

        // 带换行输出结果（每80个字符一行）
        printWithNewlines(result)
    } catch (e: Exception) {
        println("错误: 无法处理文件 - ${e.message}")
    }
}

// 读取文件内容（Kotlin/Native 原生文件操作）
private fun readFile(filename: String): List<Byte> {
    val file = fopen(filename, "r") ?: throw Exception("无法打开文件: $filename")
    return try {
        val bufferSize = 1024 * 1024 // 1MB 缓冲区
        val buffer = ByteArray(bufferSize)
        val data = mutableListOf<Byte>()

        while (true) {
            val bytesRead = fread(
                buffer.refTo(0),
                1UL,
                bufferSize.toULong(),
                file
            ).toInt()

            if (bytesRead <= 0) break
            for (i in 0 until bytesRead) {
                data.add(buffer[i])
            }
        }
        data
    } finally {
        fclose(file)
    }
}

// 生成反向互补序列
private fun reverseComplement(input: ByteArray, complement: ByteArray): ByteArray {
    val n = input.size
    val result = ByteArray(n)

    for (i in 0 until n) {
        val c = input[n - 1 - i].toInt() and 0xFF // 确保无符号
        result[i] = complement[c]
    }

    return result
}

// 带换行输出（每80个字符一行）
private fun printWithNewlines(data: ByteArray) {
    val lineLength = 80
    var totalWritten = 0
    val dataSize = data.size

    while (totalWritten < dataSize) {
        // 计算当前行应输出的字符数
        val remaining = dataSize - totalWritten
        val bytesToWrite = minOf(remaining, lineLength)

        // 输出当前行
        val bytesWritten = fwrite(
            data.refTo(totalWritten),
            1UL,
            bytesToWrite.toULong(),
            stdout
        ).toInt()

        if (bytesWritten <= 0) break
        totalWritten += bytesWritten

        // 如果不是最后一行，输出换行符
        if (totalWritten < dataSize) {
            fwrite("\n".refTo(0), 1UL, 1UL, stdout)
        }
    }
    // 最后添加一个换行符
    fwrite("\n".refTo(0), 1UL, 1UL, stdout)
    fflush(stdout)
}
